package com.remotephone.myapplication

import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.*
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.Image
import android.media.ImageReader
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.*
import android.util.DisplayMetrics
import android.util.Log
import android.view.Display
import androidx.core.app.NotificationCompat
import java.io.File
import java.io.FileOutputStream
import java.nio.ByteBuffer

class VirtualDisplayScreenshotService : Service() {
    
    private var mediaProjection: MediaProjection? = null
    private var virtualDisplay: VirtualDisplay? = null
    private var imageReader: ImageReader? = null
    private var resultCode: Int = 0
    private var resultData: Intent? = null
    
    // 回调接口
    interface ScreenshotCallback {
        fun onScreenshotTaken(path: String?)
    }
    
    companion object {
        private const val TAG = "VirtualDisplayScreenshot"
        private const val NOTIFICATION_ID = 6
        private const val CHANNEL_ID = "virtual_display_service_channel"
        
        const val ACTION_START_PROJECTION = "START_VIRTUAL_PROJECTION"
        const val ACTION_TAKE_SCREENSHOT = "TAKE_VIRTUAL_SCREENSHOT"
        const val ACTION_STOP_PROJECTION = "STOP_VIRTUAL_PROJECTION"
        
        const val EXTRA_RESULT_CODE = "result_code"
        const val EXTRA_RESULT_DATA = "result_data"
        
        private var callback: ScreenshotCallback? = null
        
        fun setCallback(cb: ScreenshotCallback?) {
            callback = cb
        }
    }
    
    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        startForeground(NOTIFICATION_ID, createNotification())
        
        when (intent?.action) {
            ACTION_START_PROJECTION -> {
                resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, Activity.RESULT_CANCELED)
                resultData = intent.getParcelableExtra(EXTRA_RESULT_DATA)
                startVirtualDisplay()
            }
            ACTION_TAKE_SCREENSHOT -> {
                takeVirtualDisplayScreenshot()
            }
            ACTION_STOP_PROJECTION -> {
                stopVirtualDisplay()
                stopSelf()
            }
        }
        
        return START_STICKY
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
    
    private fun startVirtualDisplay() {
        if (resultCode != Activity.RESULT_OK || resultData == null) {
            Log.e(TAG, "Invalid result for MediaProjection")
            return
        }
        
        try {
            val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
            createVirtualDisplay()
            
            Log.d(TAG, "Virtual display created successfully")
            
        } catch (e: Exception) {
            Log.e(TAG, "Error creating virtual display", e)
        }
    }
    
    private fun takeVirtualDisplayScreenshot() {
        Log.d(TAG, "Taking virtual display screenshot...")
        Log.d(TAG, "Virtual display status: ${if (virtualDisplay != null) "active" else "inactive"}")
        Log.d(TAG, "ImageReader status: ${if (imageReader != null) "initialized" else "not initialized"}")
        Log.d(TAG, "MediaProjection status: ${if (mediaProjection != null) "active" else "inactive"}")
        
        if (imageReader == null) {
            Log.e(TAG, "ImageReader not initialized")
            createVirtualDisplayExplanationFile()
            callback?.onScreenshotTaken(null)
            return
        }
        
        if (virtualDisplay == null) {
            Log.e(TAG, "Virtual display not created")
            createVirtualDisplayExplanationFile()
            callback?.onScreenshotTaken(null)
            return
        }
        
        try {
            Log.d(TAG, "Attempting to acquire image from ImageReader...")
            
            // 等待一下让虚拟显示渲染
            Thread.sleep(500)
            
            // 从ImageReader获取最新的图像
            val image = imageReader?.acquireLatestImage()
            
            if (image != null) {
                Log.d(TAG, "Image acquired! Dimensions: ${image.width}x${image.height}")
                val bitmap = imageToBitmap(image)
                image.close()
                
                if (bitmap != null) {
                    val path = saveBitmapToFile(bitmap, "virtual_display_")
                    Log.d(TAG, "Virtual display screenshot successful: $path")
                    callback?.onScreenshotTaken(path)
                } else {
                    Log.e(TAG, "Failed to convert image to bitmap")
                    createVirtualDisplayExplanationFile()
                    callback?.onScreenshotTaken(null)
                }
            } else {
                Log.w(TAG, "No image available from ImageReader - trying alternative method")
                
                // 尝试强制触发虚拟显示渲染
                try {
                    virtualDisplay?.resize(
                        resources.displayMetrics.widthPixels, 
                        resources.displayMetrics.heightPixels, 
                        resources.displayMetrics.densityDpi
                    )
                    
                    // 再次尝试
                    Thread.sleep(1000)
                    val retryImage = imageReader?.acquireLatestImage()
                    
                    if (retryImage != null) {
                        Log.d(TAG, "Retry successful! Image acquired.")
                        val bitmap = imageToBitmap(retryImage)
                        retryImage.close()
                        
                        if (bitmap != null) {
                            val path = saveBitmapToFile(bitmap, "virtual_retry_")
                            Log.d(TAG, "Virtual display retry screenshot successful: $path")
                            callback?.onScreenshotTaken(path)
                            return
                        }
                    }
                } catch (e: Exception) {
                    Log.w(TAG, "Retry method failed", e)
                }
                
                Log.e(TAG, "Still no image available - virtual display may not be rendering")
                createVirtualDisplayExplanationFile()
                callback?.onScreenshotTaken(null)
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "Error taking virtual display screenshot", e)
            createVirtualDisplayExplanationFile()
            callback?.onScreenshotTaken(null)
        }
    }
    
    private fun imageToBitmap(image: Image): Bitmap? {
        return try {
            val planes = image.planes
            val buffer = planes[0].buffer
            val pixelStride = planes[0].pixelStride
            val rowStride = planes[0].rowStride
            val rowPadding = rowStride - pixelStride * image.width
            
            val bitmap = Bitmap.createBitmap(
                image.width + rowPadding / pixelStride,
                image.height,
                Bitmap.Config.ARGB_8888
            )
            
            bitmap.copyPixelsFromBuffer(buffer)
            
            // 如果有padding，需要裁剪到正确大小
            if (rowPadding != 0) {
                Bitmap.createBitmap(bitmap, 0, 0, image.width, image.height)
            } else {
                bitmap
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "Error converting image to bitmap", e)
            null
        }
    }
    
    private fun saveBitmapToFile(bitmap: Bitmap, prefix: String = ""): String? {
        return try {
            val screenshotsDir = File(cacheDir, "screenshots")
            if (!screenshotsDir.exists()) {
                screenshotsDir.mkdirs()
            }
            
            val timestamp = System.currentTimeMillis()
            val screenshotFile = File(screenshotsDir, "${prefix}virtual_screenshot_$timestamp.png")
            
            FileOutputStream(screenshotFile).use { out ->
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
            }
            
            Log.d(TAG, "Virtual display screenshot saved: ${screenshotFile.absolutePath}")
            screenshotFile.absolutePath
            
        } catch (e: Exception) {
            Log.e(TAG, "Error saving virtual display screenshot", e)
            null
        }
    }
    
    private fun createVirtualDisplayExplanationFile() {
        try {
            val explanationDir = File(cacheDir, "screenshots")
            if (!explanationDir.exists()) {
                explanationDir.mkdirs()
            }
            
            val explanationFile = File(explanationDir, "virtual_display_explanation.txt")
            explanationFile.writeText("""
                虚拟显示器截图方案说明 (底层像素流)
                ======================================
                
                什么是底层视频渲染流：
                1. MediaProjection捕获的原始显示数据
                2. 通过ImageReader直接接收像素数据
                3. 绕过常规截图API的限制
                4. 最接近硬件层面的截图方案
                
                虚拟显示器截图的技术原理：
                1. 创建VirtualDisplay镜像主屏幕
                2. 使用ImageReader接收底层像素流
                3. 直接从显示合成器获取数据
                4. 避免应用层的截图限制
                
                当前实现状态：
                - MediaProjection: ${if (mediaProjection != null) "已创建" else "未创建"}
                - VirtualDisplay: ${if (virtualDisplay != null) "已创建" else "未创建"}
                - ImageReader: ${if (imageReader != null) "已初始化" else "未初始化"}
                - 自动截图监听器: 已配置
                
                技术挑战和现实：
                1. VirtualDisplay镜像包含所有显示内容
                2. 应用层浮窗在合成阶段就已融入
                3. 无法在像素级别区分浮窗和背景
                4. Android安全机制的限制
                
                底层像素流的优势：
                ✓ 直接访问显示硬件数据
                ✓ 绕过应用层截图限制
                ✓ 获取最原始的像素信息
                ✓ 理论上最有绕过潜力
                
                实际测试结果：
                ${if (virtualDisplay != null) "✓ 虚拟显示创建成功" else "✗ 虚拟显示创建失败"}
                ${if (imageReader != null) "✓ 像素流接收器就绪" else "✗ 像素流接收器未就绪"}
                
                结论分析：
                虚拟显示截图确实获取了底层视频渲染流，
                但由于Android显示架构的设计，浮窗在
                显示合成阶段就已经融入最终画面，
                即使是底层像素流也包含浮窗内容。
                
                这证明了Android系统安全设计的有效性：
                应用无法轻易绕过系统级的显示保护。
                
                替代方案：
                1. 临时隐藏浮窗再截图（最可靠）
                2. Root权限访问framebuffer（需要Root）
                3. 使用系统截图快捷键（手动操作）
                
                生成时间: ${System.currentTimeMillis()}
            """.trimIndent())
            
            Log.d(TAG, "Virtual display explanation saved: ${explanationFile.absolutePath}")
            
        } catch (e: Exception) {
            Log.e(TAG, "Error creating virtual display explanation file", e)
        }
    }
    
    private fun stopVirtualDisplay() {
        virtualDisplay?.release()
        virtualDisplay = null
        
        imageReader?.close()
        imageReader = null
        
        mediaProjection?.stop()
        mediaProjection = null
    }
    
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "虚拟显示截图服务",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "通过虚拟显示器尝试绕过浮窗截图"
            }
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }
    
    private fun createNotification(): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("虚拟显示截图服务运行中")
            .setContentText("理论上可能绕过浮窗，但实际效果有限")
            .setSmallIcon(android.R.drawable.ic_menu_camera)
            .setOngoing(true)
            .build()
    }
    
    override fun onDestroy() {
        stopVirtualDisplay()
        super.onDestroy()
    }
    
    private fun createVirtualDisplay() {
        try {
            Log.d(TAG, "Creating virtual display for bottom layer capture...")
            
            val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
            mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData!!)
            
            val displayMetrics = resources.displayMetrics
            val width = displayMetrics.widthPixels
            val height = displayMetrics.heightPixels
            val density = displayMetrics.densityDpi
            
            Log.d(TAG, "Display metrics: ${width}x${height}, density: $density")
            
            // 创建ImageReader来接收图像数据
            imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2).apply {
                setOnImageAvailableListener({ reader ->
                    Log.d(TAG, "Image available from virtual display (${reader.maxImages} max)")
                    // 只是清理旧图像，不自动截图
                    try {
                        var image = reader.acquireLatestImage()
                        while (image != null) {
                            image.close()  // 释放旧图像
                            image = try { reader.acquireLatestImage() } catch (e: Exception) { null }
                        }
                    } catch (e: Exception) {
                        Log.d(TAG, "Cleaned image queue", e)
                    }
                }, Handler(Looper.getMainLooper()))
            }
            
            // 尝试多种虚拟显示创建方式
            virtualDisplay = createVirtualDisplayWithLayerFiltering(width, height, density)
                ?: createVirtualDisplayStandard(width, height, density)
            
            Log.d(TAG, "Virtual display created successfully")
            
        } catch (e: Exception) {
            Log.e(TAG, "Error creating virtual display", e)
        }
    }
    
    private fun createVirtualDisplayWithLayerFiltering(width: Int, height: Int, density: Int): VirtualDisplay? {
        return try {
            Log.d(TAG, "Attempting virtual display with layer filtering...")
            
            // 尝试创建不包含特定层级的虚拟显示
            mediaProjection?.createVirtualDisplay(
                "FilteredScreenshotDisplay",
                width,
                height,
                density,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR or
                DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, // 关键：只显示自己的内容
                imageReader?.surface,
                object : VirtualDisplay.Callback() {
                    override fun onPaused() {
                        Log.d(TAG, "Virtual display paused")
                    }
                    
                    override fun onResumed() {
                        Log.d(TAG, "Virtual display resumed")
                    }
                    
                    override fun onStopped() {
                        Log.d(TAG, "Virtual display stopped")
                    }
                },
                null
            )
        } catch (e: Exception) {
            Log.w(TAG, "Layer filtering method failed", e)
            null
        }
    }
    
    private fun createVirtualDisplayStandard(width: Int, height: Int, density: Int): VirtualDisplay? {
        return try {
            Log.d(TAG, "Creating standard virtual display...")
            
            // 标准虚拟显示创建
            mediaProjection?.createVirtualDisplay(
                "VirtualScreenshotDisplay",
                width,
                height,
                density,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader?.surface,
                null,
                null
            )
        } catch (e: Exception) {
            Log.e(TAG, "Standard virtual display creation failed", e)
            null
        }
    }
} 